import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:x3_component_core/components/scroll_components/base_message_container_component.dart';

class BaseMessageController extends ChangeNotifier {
  ///刷新
  void refresh() {
    notifyListeners();
  }
}

class BaseMessageComponent extends StatefulWidget {
  /// 请求的服务地址
  final String path;

  /// 请求的方式
  final BaseHttpMethodEnum method;

  /// 构建Item项
  final Widget Function(Map<String, dynamic> item, int index) buildItem;

  /// 构建 separator
  final Widget Function(Map<String, dynamic> item) separatorBuilder;

  /// 是否是分页查询
  final bool isPaging;

  /// 刷新列表控制器
  final BaseMessageController controller;

  /// 参数
  final Map<String, dynamic> params;

  /// 刷新数据加载完成事件
  final Function(List<Map<String, dynamic>> items) refreshDataLoadComplete;

  /// 内边距
  final EdgeInsets padding;

  /// 预加载
  final double cacheExtent;

  BaseMessageComponent({
    Key key,
    @required this.path,
    @required this.buildItem,
    @required this.controller,
    this.padding = EdgeInsets.zero,
    this.separatorBuilder,
    this.method = BaseHttpMethodEnum.POST,
    this.isPaging = true,
    this.refreshDataLoadComplete,
    this.params = const {},
    this.cacheExtent,
  }) : super(key: key);

  @override
  _BaseMessageComponentState createState() => _BaseMessageComponentState();
}

class _BaseMessageComponentState extends State<BaseMessageComponent> {
  /// 当前是第几页
  int pageIndex = 1;

  /// 每页显示多少条数
  int pageSize = 15;

  /// 下拉刷新组件
  GlobalKey<RefreshIndicatorState> _refreshIndicatorState;
  BaseMessageController _messageController;

  /// 获取数据
  Future<BaseHttpResultModel> _getItems() async {
    if (widget.path == null || widget.path.isEmpty) {
      return BaseHttpResultModel(BaseDioCodeUtil.success_code, true, [], null, null);
    }
    Map<String, dynamic> params = new HashMap();
    if (widget.params != null) params.addAll(widget.params);
    if (widget.isPaging == true) {
      Map<String, dynamic> pageParams = {'pageIndex': pageIndex, 'pageSize': pageSize};
      params.addAll(pageParams);
    }
    BaseHttpResultModel result = await dioUtil.fetch(widget.path, method: widget.method, params: params);
    return result;
  }

  /// 刷新数据
  Future<List<Map<String, dynamic>>> _onRefresh() async {
    this.pageSize = pageIndex * pageSize;
    this.pageIndex = 1;
    BaseHttpResultModel result = await _getItems();
    List<dynamic> datas = [];
    this.pageSize = 15;
    if (result.success == true && result.data is List) datas = result.data;
    List<Map<String, dynamic>> items = BaseDioCodeUtil.dynamicListToMapList(datas);
    return items.reversed.toList();
  }

  /// 加载更多数据
  Future<List<Map<String, dynamic>>> _onLoading() async {
    this.pageIndex = this.pageIndex + 1;
    BaseHttpResultModel result = await _getItems();
    List<dynamic> datas = [];
    if (result.success == true && result.data is List) {
      datas = result.data;
      if (datas.length == 0) {
        this.pageIndex -= 1;
      }
    } else {
      this.pageIndex -= 1;
    }
    List<Map<String, dynamic>> items = BaseDioCodeUtil.dynamicListToMapList(datas);
    return items;
  }

  @override
  void initState() {
    super.initState();
    _messageController = widget.controller ?? BaseMessageController();
    _messageController.addListener(() {
      this._refreshIndicatorState.currentState.show(atTop: false);
    });
  }

  @override
  Widget build(BuildContext context) {
    return BaseMessageContainerComponent(
      builder: (BuildContext context, int index, dynamic item) => widget.buildItem(item, index),
      separatorBuilder: (BuildContext context, int index, dynamic item) {
        return widget.separatorBuilder != null ? widget.separatorBuilder(item) : SizedBox(height: 0);
      },
      getRefreshIndicatorState: (GlobalKey<RefreshIndicatorState> refreshIndicatorState) {
        this._refreshIndicatorState = refreshIndicatorState;
      },
      needLoading: widget.isPaging,
      onRefresh: _onRefresh,
      onLoading: _onLoading,
      padding: widget.padding,
      cacheExtent: widget.cacheExtent,
      refreshDataLoadComplete: (List<Map<String, dynamic>> items) {
        if (widget.refreshDataLoadComplete != null) widget.refreshDataLoadComplete(items.reversed.toList());
      },
    );
  }
}
